package com.jinzhi.common.utils;

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author: mcf
 * @CreateTime: 2024/06/05
 * @Description: 重写copyProperties
 */
public class CustomBeanUtils {


    public static void copyNonNullProperties(Object source, Object target) throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        // 获取源对象和目标对象的属性描述符
        PropertyDescriptor[] sourceDescriptors = Introspector.getBeanInfo(source.getClass()).getPropertyDescriptors();
        PropertyDescriptor[] targetDescriptors = Introspector.getBeanInfo(target.getClass()).getPropertyDescriptors();

        // 遍历源对象的属性
        for (PropertyDescriptor sourceDescriptor : sourceDescriptors) {
            String propertyName = sourceDescriptor.getName();

            // 忽略class等元信息属性
            if ("class".equals(propertyName)) {
                continue;
            }

            // 检查目标对象是否也有此属性
            PropertyDescriptor targetDescriptor = null;
            for (PropertyDescriptor desc : targetDescriptors) {
                if (desc.getName().equals(propertyName)) {
                    targetDescriptor = desc;
                    break;
                }
            }

            if (targetDescriptor == null) {
                continue; // 目标对象没有此属性，跳过
            }

            // 获取属性的读写方法
            Method sourceReadMethod = sourceDescriptor.getReadMethod();
            Method targetWriteMethod = targetDescriptor.getWriteMethod();

            if (sourceReadMethod != null && targetWriteMethod != null) {
                // 读取源对象的属性值
                Object value = sourceReadMethod.invoke(source);

                // 检查属性值是否非null且非默认，并且类型匹配
                if (value != null && !isDefaultValue(value, targetDescriptor.getPropertyType()) &&
                        sourceDescriptor.getPropertyType().equals(targetDescriptor.getPropertyType())) {
                    // 类型匹配，复制属性值到目标对象
                    targetWriteMethod.invoke(target, value);
                }
            }
        }
    }

    // 这是一个示例方法，用于检查值是否为默认值。这里需要根据实际情况来定义。
    // 例如，对于字符串，空字符串可能被视为默认值；对于Integer，0可能被视为默认值。
    private static boolean isDefaultValue(Object value, Class<?> type) {
        if (value == null) {
            return true; // null 总是被视为默认值
        }

        // 这里可以添加其他类型的检查...

        // 示例：对于字符串，检查是否为空字符串
        if (type == String.class) {
            return (value.toString()).isEmpty();
        }

        // 对于其他类型，这里返回false，表示不是默认值
        return false;
    }

}
